SpringBoot项目集成【用户身份认证】实战 【技术选型篇】基于Session、Token、JWT怎么选? | 您所在的位置:网站首页 › springboot jwt认证 › SpringBoot项目集成【用户身份认证】实战 【技术选型篇】基于Session、Token、JWT怎么选? |
在上文,我们实现了基于SpringBoot项目的API接口开发,并实现 API结果统一封装、支持跨域请求等等功能,接下来做的是开发登录接口,实现一套统一鉴权的用户身份认证的机制。 我已经提前和狗哥(博客主页) 一起讨论确定了认证机制,会采用目前流行的基于JWT的Token用户身份认证机制,主流程如下: 前端请求【用户名+密码登录】接口,后端验证通过后生成Token 返回给前端;前端保存Token,以后每次请求API都会携带Token,后端校验Token通过就正常返回数据;直到后端校验Token已失效,这时再从第1步重新开始。![]() 为什么这么选型?我们都考虑了哪些点? OK,那我也很乐意和大家一起探讨:怎么做好用户身份认证! 网上很多文章大多直接整合JWT,并没有讲解 为什么选择JWT?与其它选型对比有什么优缺点? 这些都是我们实战的基础,也会让我们代码写的清清楚楚、明明白白。不管写毕业设计,这是面试谈项目亮点,本文也将是你可以参考的点! 用户身份认证很重要,很多小细节,等你收割!相信本文一定会让你有所收获!OK,Let’s go! PS,完整的用户身份认证代码早已实现,和狗哥也已联调通过,正在赶工博文,预告一下我将分三篇来写,非常详细,料很足,准备好发车喽,Let’s go! 【技术选型篇】基于Session、Token、JWT怎么选?因为可能还有很多同学还不清楚上下文,所以简单介绍一下这个专栏要做的事: 天罡老哥和狗哥(博客主页)有意从0到1带大家搭建一个SpringBoot+SpringCloud+Vue的前后端分离项目! 打造一个短小精悍、技术主流、架构规范的前后端分离实战项目!我负责后端,狗哥负责前端! 目的就是让大家通过项目实战,学到一些真东西,将所学理论落地,助力有心强大的你更快的成长!开启你的工作之旅,让开发游刃有余! 详细的后端规划和后端大纲思维导图在开篇已经给出,专栏的总进度如下: SpringBoot+Vue前后端分离项目实战 - 服务端部分1. 基于SpringBoot+SpringCloud+Vue前后端分离项目实战 --开篇2. 天狗实战SpringBoot+Vue(一)环境安装3. 天狗实战SpringBoot+Vue(二)项目结构搭建(上)4. 天狗实战(二)SpringBoot API开发详解 --SpringMVC注解+封装结果+支持跨域+打包(下)5. Maven依赖加载不进来? 依赖加载失败? 你值得掌握如何排查的方法6. 实战Git常用操作(IDEA界面+命令):初始化(init)、忽略文件(.gitignore)、提交(commit)、查看提交记录(log)、创建+切换分支(branch)Vue + SpringBoot前后端分离项目实战 - 前端部分1. 手把手带你做一套毕业设计-征程开启2. 我应该把毕业设计做到什么程度才能过关?3. 做毕业设计,前端部分你需要掌握的6个核心技能4. 基于Vue+Vue-cli+webpack搭建渐进式高可维护性前端实战项目5. 基于Vue+Less+axios封装+ElementUI搭建项目底层支撑实战6. 使用Vue+vue-router+路由守卫实现路由鉴权功能实战提前说明: 因为HTTP 是无状态的协议,每个请求都是完全独立的,服务端无法确认当前访问者的身份信息,无法分辨上一次的请求发送者和这一次的发送者是不是同一个人,所以就需要在用户登录后进行登录态的管理。 一、基于Cookie的Session(会话)认证机制其中有一种是基于Session的方式,是一种记录服务端和浏览器会话状态的机制,大致的流程如下: 登录成功后,服务端根据用户信息生成唯一标识SessionId ,比如根据用户ID+加随机盐salt,然后进行各种加密生成 服务端保存SessionId以及对应的用户信息,比如保存在内存或Redis等,需要维护过期时间。然后将SessionId写入Cookie。 前端请求API时会自动携带Cookie中的SessionId,服务端通过SessionId获取Session进行校验: 如果找到 Session 证明用户已经登录,进行后续处理;如果未找到Session说明用户没有登录或者登录失效,这时再从第1步重新开始。基于Token的认证方式,又分为两种: 1. 有状态的Token有状态的Token方式,服务端需要保存Token数据 比如, 将基于Cookie的Session方式变一变,不基于Cookie了,而是由前端自行维护Token,大致的流程如下: 登录成功后,服务端根据用户信息生成唯一标识TokenId ,比如根据用户ID+加随机盐salt,然后进行各种加密生成 服务端保存TokenId以及对应的用户信息,比如保存在内存或Redis等,需要维护过期时间。然后将TokenId返回给前端。 因为不基于Cookie,所以前端需要自行保存TokenId,比如保存在localStorage等,请求API时控制携带TokenId,服务端通过TokenId去内存或Redis搜索匹配的Token: 如果找到Token,证明用户已经登录,进行后续处理;如果未找到Token,说明用户没有登录或者登录失效,这时再从第1步重新开始。当Token不需要保存除用户ID之外的信息时,Token就等于TokenId,只是保存的信息变少,但仍然需要服务端保存,例如保存在内存中的话就是数据结构用Map还是Set的区别,或者Map的value是不是空的区别。 好处: 因为Token完全由前端维护,不基于Cookie,所以可以避免CSRF攻击、支持跨域、对移动端友好。 缺点: 和Session方式有同样的缺点:服务端需要存储Token,维护过期时间,占用服务器资源,在分布式应用中还需要维护Token同步,另外校验时需要读取Token当然还有其它场景: 比如,你申请调用第三方平台的接口,它会为你生成一个一直有效的Token,那么这个Token就是保存在第三方的服务端,也是有状态的。再比如,你可能听说过refresh_token,用于刷新access_token,access_token可以不用在服务端保存,但refresh_token还需要保存在服务端,这些都可以称为有状态的。 2. 无状态的Token无状态的Token方式,服务端不用保存Token数据,是不是听上去很历害?大致的流程如下: 登录成功后,服务端生成Token 返回给前端;前端保存Token,比如保存在localStorage等,请求API时控制携带Token,服务端接收后校验Token: 校验Token通过,进行后续处理;校验Token不通过,说明用户没有登录或者登录失效,这时再从第1步重新开始。JWT (JSON Web Token) 是一种开放标准(RFC 7519)定义的JSON对象,本质是一个字符串,正是无状态Token中的一种。那它是如何做到不用服务端保存,仅通过自身就能完成校验? 这和人民币防伪有点类似,是因为它本身既包含用户信息等数据,也包含过期时间和数字签名,虽然数据经过传输,但接收方仍可以直接校验它是否过期、是否被篡改! 还没理解?那我们看一下它的组成: 如上图右侧是解码后的数据,左侧是JWT字符串,由图中3种颜色代表的3个部分组成(以逗号连接): 1Header.2Payload.3Signature 1. Header元数据,定义了生成签名的算法以及 Token 的类型。 {"typ": "JWT","alg": "RS256" }typ:表示Token类型,JWT统一为JWT alg:表示签名算法,像RS256、HS256 2. Payload载荷,是传递数据的载体,包含7个内置字段: String ISSUER = "iss"; // 发行人 String SUBJECT = "sub"; // 主题 String EXPIRES_AT = "exp"; // 失效时间 String NOT_BEFORE = "nbf"; // 在此之前不可用 String ISSUED_AT = "iat"; // 发布时间 String JWT_ID = "jti"; // JWT id值 String AUDIENCE = "aud"; // 用户重点是 exp 失效时间 ,其它可选使用,例如:我可以将 iss 指定保存userId 用户信息就保存在这里,上面7个不够的话,还可以自定义字段,例如:我自定义了userName: {"sub": "TgAuthSSO","nbf": 1679984611,"iss": "1","exp": 1679984911,"userName": "张三","iat": 1679984611 }注意:payload中数据默认未加密,所以不适合放隐私信息字段,比如用户的密码等,防止信息泄露。 3. Signature签名,这是JWT防止内容被篡改的关键! 通过使用 Header 里面指定的签名算法,对Payload和Header加密而生成。 四、为什么选择JWT? 1. 安全数据被签名加密后,可以有效防止内容被篡改。 例如:RSA算法,目前仍是非常可靠的加密算法,极难破解! 2. 无状态【无状态】是相对【有状态】而言,【有状态】是指服务器端需要保存数据。 JWT由于其自带校验的所有数据,本身就可以验证Token是否被篡改、是否合法、是否过期,所以不需要在服务器存储Token,对于分布式场景省去了很多麻烦,更主要的是节省了服务器资源! 3. 可自定义字段能够在Payload中自定义存储字段,保证了扩展性,可以把常用数据写进去,避免数据的二次读取。 最后如果觉得写的不错,订阅起来吧,后面还有更多干货输出… ,我会针对订阅的同学做针对性的指导,让你能轻松的将项目完整实战跟下来,OK,就说这么多了,我们下文见! 另外,别忘了关注天哥:天罡gg ,发布新文不容易错过: https://blog.csdn.net/scm_2008 老规矩,请投票给我反馈,谢谢大家的支持! |
今日新闻 |
推荐新闻 |
专题文章 |
CopyRight 2018-2019 实验室设备网 版权所有 |